home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Revolution - Das Atari CD Magazin 1997
/
Revolution - Das Atari CD Magazin 1.iso
/
software
/
anwendng
/
qed_397
/
sourcen
/
desktop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-04
|
35KB
|
1,319 lines
#include "global.h"
#include "av.h"
#include "clipbrd.h"
#include "disk.h"
#include "edit.h"
#include "file.h"
#include "icon.h"
#include "makro.h"
#include "menu.h"
#include "obj.h"
#include "options.h"
#include "rsc.h"
#include "set.h"
#include "text.h"
#include "version.h"
#include "windows.h"
#include "desktop.h"
#define KIND (NAME|CLOSER|FULLER|MOVER|SIZER|UPARROW|DNARROW|VSLIDE|LFARROW|RTARROW|HSLIDE)
#define KIND2 (NAME|CLOSER|MOVER)
#define FLAGS (WI_NONE)
#define XFAC sys_wchar /* X-Faktor */
#define YFAC sys_hchar /* Y-Faktor */
#define INITX (2 * sys_wchar) /* X-Anfangsposition */
#define INITY (6 * sys_hchar) /* Y-Anfangsposition */
#define INITW (desk.x + desk.w - 6*sys_wchar) /* Anfangsbreite in Pixel */
#define INITH (desk.y + desk.h - 10*sys_hchar) /* Anfangshöhe in Pixel */
#define ICON_RASTER_X (icons[IDISK].ob_width+2)
#define ICON_RASTER_Y (icons[IDISK].ob_height+2)
/* lokale Variablen ********************************************************/
LOCAL BOOLEAN killed = FALSE, destruct = FALSE;;
LOCAL SET used_icons;
/* lokale Prototypen *******************************************************/
LOCAL VOID draw_winobject (WINDP window, WORD obj);
LOCAL VOID draw_box (CONST RECT *box, WORD x_offset, WORD y_offset);
LOCAL VOID draw_all (WORD num_boxes, CONST RECT *boxes, WORD x_offset, WORD y_offset);
LOCAL VOID check_drag (WORD x_offset, WORD y_offset, CONST RECT *bound, CONST RECT *inner, RECT *diff);
LOCAL BOOLEAN drag_react (WORD src_obj, WORD dest_obj);
LOCAL VOID drag_objs (WINDP window, SET objs, WORD m_x, WORD m_y);
LOCAL VOID get_selected (WINDP window, SET objs, RECT *area);
LOCAL VOID select_objs (WINDP window, SET objs);
LOCAL VOID clear_objs (WINDP window, SET objs);
LOCAL VOID invert_objs (WINDP window, SET objs);
LOCAL VOID rubber_objs (WINDP window, MKINFO *mk);
LOCAL BOOLEAN in_icon (WORD mox, WORD moy, OBJECT *dialog, WORD obj);
LOCAL VOID wi_draw (WINDP window, CONST RECT *r);
LOCAL VOID wi_click (WINDP window, MKINFO *mk);
LOCAL VOID wi_unclick (WINDP window);
LOCAL BOOLEAN wi_key (WINDP window, MKINFO *mk);
LOCAL BOOLEAN check_end (WORD action);
LOCAL VOID icon_exist (WORD icon, SET actions);
LOCAL BOOLEAN icon_test (WORD icon, WORD action);
LOCAL WORD icon_edit (WORD icon, WORD action);
LOCAL VOID crt_desktop (WORD icon, WINDP window);
LOCAL BOOLEAN open_desktop (VOID);
/***************************************************************************/
LOCAL BOOLEAN check_end(WORD action)
{
WORD anz, i;
WORD ic, icp[MAX_ICON_ANZ];
SET actions;
if (action==DO_DESTRUCT && makro_rec)
return FALSE;
anz = all_icons(icp);
/* Erst alle testen, dann alle killen */
i = anz;
while ((--i)>=0)
{
ic = icp[i];
if (ic!=0)
{
Icon_exist(ic,actions);
if (setin(actions,action))
if (!Icon_test(ic,action))
return FALSE;
}
}
if (makro_rec)
end_rec(FALSE);
if (action==DO_DESTRUCT && (save_opt==0)!=(global_shift==0))
option_save(FALSE);
i = anz;
if (action==DO_DESTRUCT)
destruct = TRUE;
while ((--i)>=0)
{
ic = icp[i];
if (ic!=0)
{
Icon_exist(ic,actions);
if (setin(actions,action))
Icon_edit(ic,action);
}
}
destruct = FALSE;
return TRUE;
}
/***************************************************************************/
/* Operation vorhanden ? */
/***************************************************************************/
LOCAL VOID icon_exist(WORD icon, SET actions)
{
setclr(actions);
setincl(actions,DO_DESTRUCT);
setincl(actions,DO_OPEN);
setincl(actions,DO_HELP);
setincl(actions,DO_INFO);
setincl(actions,DO_FIND);
if (!no_desktop)
setincl(actions,DO_SELALL);
}
/***************************************************************************/
/* Operation testen */
/***************************************************************************/
LOCAL BOOLEAN icon_test(WORD icon, WORD action)
{
BOOLEAN erg;
switch(action)
{
case DO_DESTRUCT:
if (killed) /* Wird bei AC_CLOSE aufgerufen */
erg = TRUE;
else
erg = check_end(DO_DESTRUCT);
break;
case DO_OPEN :
if (killed && (long)Malloc(-1L) < 55000L)
{
note(1,NOMEMORY);
erg = FALSE;
}
else
erg = TRUE;
break;
case DO_INFO :
erg = TRUE;
break;
case DO_SELALL :
erg = (!no_desktop);
break;
case DO_FIND :
erg = Icon_test(idisk, DO_FIND);
break;
case DO_HELP :
erg = TRUE; break;
default:
erg = FALSE;
}
return erg;
}
/***************************************************************************/
/* Operation durchführen */
/***************************************************************************/
LOCAL WORD icon_edit(WORD icon, WORD action)
{
WORD erg = 1;
WINDP window;
window = get_window (0);
switch(action)
{
case DO_CLOSE :
if (window->opened)
close_window(window);
done = TRUE;
break;
case DO_DESTRUCT:
if (!killed) /* Wird bei AC_CLOSE aufgerufen */
{
if (window->opened)
close_window(window);
kill_memory();
killed = TRUE;
done = TRUE;
}
break;
case DO_OPEN :
if (killed)
{
do_all_icon(ALL_TYPES,DO_REINIT);
killed = FALSE;
}
if (!open_desktop())
erg = -1;
break;
case DO_SELALL :
if (window!=sel_window)
unclick_window();
select_objs(window,used_icons);
setcpy(sel_objs,used_icons);
sel_window = setcmp (sel_objs, NULL) ? NULL : window;
break;
case DO_INFO :
info_desktop();
erg = TRUE;
break;
case DO_FIND :
erg = Icon_edit(idisk, DO_FIND);
break;
case DO_HELP :
erg = call_hyp("main");
break;
}
return erg;
}
/***************************************************************************/
LOCAL VOID draw_box (CONST RECT *box, WORD x_offset, WORD y_offset)
{
WORD xy[10];
WORD m1, m2;
xy[2] = xy[0] = x_offset + box->x; /* Dieser Teil ist RICHTIG !!! */
xy[7] = xy[1] = y_offset + box->y;
xy[3] = xy[1] + box->h-1;
xy[4] = xy[0] + box->w-1;
*(long*)(xy+5) = *(long*)(xy+3);
*(long*)(xy+8) = *(long*)(xy+0); /* Punkt 0 ist gleich Punkt 5 */
m1 = 0xAAAA; m2 = 0x5555;
vsl_udsty (vdi_handle, odd (xy[0]+xy[1]) ? m1 : m2);
v_pline (vdi_handle, 2, &xy[0]);
vsl_udsty (vdi_handle, odd (xy[3]) ? m1 : m2);
v_pline (vdi_handle, 2, &xy[2]);
vsl_udsty (vdi_handle, odd (xy[4]+xy[5]) ? m1 : m2);
v_pline (vdi_handle, 2, &xy[4]);
vsl_udsty (vdi_handle, odd (xy[7]) ? m1 : m2);
v_pline (vdi_handle, 2, &xy[6]);
} /* draw_box */
/***************************************************************************/
LOCAL VOID draw_all (WORD num_boxes, CONST RECT *boxes, WORD x_offset, WORD y_offset)
{
WORD i;
Hide_mouse ();
set_clip (TRUE, &desk);
for (i = num_boxes; (--i)>=0 ; )
draw_box (boxes++, x_offset, y_offset);
Show_mouse ();
} /* draw_all */
/***************************************************************************/
LOCAL VOID draw_winobject (WINDP window, WORD obj)
{
WORD wh, start_obj;
RECT r1, r2;
if (window!=NULL && window->opened && desktop != NULL)
{
wh = window->handle;
if (get_obtype(desktop, obj, NULL) == G_CICON)
{
/*
* Bei den Icons (z.B. Tonne) muß wegen der unterschiedlichen Größe
* der Hintergrund auch neu gezeichnet werden. Daher wird das ROOT-
* Objekt mit Clipping auf das Icon gemalt!
*/
objc_offset(desktop, obj, &r2.x, &r2.y);
r2.w = desktop[obj].ob_width;
r2.h = desktop[obj].ob_height;
start_obj = ROOT;
}
else
{
objc_rect (desktop, obj, &r2, FALSE);
start_obj = obj;
}
if (myrc_intersect (&window->work, &r2))
{
if (rc_first(wh, &r2, &r1))
do
{
objc_draw (desktop, start_obj, MAX_DEPTH, r1.x, r1.y, r1.w, r1.h);
}
while (rc_next(wh, &r1));
}
}
} /* draw_object */
/***************************************************************************/
LOCAL VOID check_drag(WORD x_offset, WORD y_offset, CONST RECT *bound, CONST RECT *inner, RECT *diff)
{
WORD i, delta;
delta = 0;
i = bound->x-(inner->x+x_offset);
if (i > 0) delta = i; /* Links heraushängend */
i = bound->x+bound->w-(inner->x+inner->w+x_offset);
if (i < 0) /* Rechts heraushängend */
{
if (delta)
delta = -x_offset; /* Keine Verschiebung */
else
delta = i;
}
x_offset += delta;
delta = 0;
i = bound->y - (inner->y+y_offset);
if (i > 0) delta = i; /* Oben heraushängend */
i = bound->y + bound->h - (inner->y + inner->h + y_offset);
if (i < 0) /* Unten heraushängend */
{
if (delta)
delta = -y_offset;
else
delta = i;
}
y_offset += delta;
diff->w = x_offset;
diff->h = y_offset;
}
LOCAL VOID drag_boxes (WORD num_objs, CONST RECT *boxes, WINDP window, SET inv_objs,
RECT *diff, const RECT *bound, MKINFO *rmk)
{
WORD event, i, obj, last_obj, kreturn;
WORD x_mstart, y_mstart; /* MausPos ganz am Anfang */
RECT inner; /* Box über alle Icons */
MKINFO mk;
OBJECT *object;
CONST RECT *ptr;
x_mstart = mk.mox = diff->x;
y_mstart = mk.moy = diff->y;
inner.x = 0; inner.y = 0; inner.w = 0; inner.h = 0;
ptr = boxes;
for (i = num_objs; (--i)>=0; ) /* Vereinigungsbox */
myrc_union (ptr++, &inner);
diff->w = diff->h = 0;
obj = last_obj = NIL;
object = NULL;
if (window != NULL) object = desktop;
if (bound == NULL) bound = &desk;
vswr_mode (vdi_handle, MD_XOR); /* Modi einstellen */
vsl_type (vdi_handle, USERLINE);
draw_all (num_objs, boxes, diff->w, diff->h);
do
{
event = evnt_multi ( MU_BUTTON | MU_M1,
1, 0x01, 0x00,
TRUE, mk.mox, mk.moy, 1, 1,
0, 0, 0, 0, 0,
NULL,
0, 0,
&mk.mox, &mk.moy,
&mk.mobutton, &mk.kstate,
&kreturn, &mk.breturn);
if (event==MU_M1) /* wenn MU_BUTTON dann hier nicht mehr rein */
{
draw_all (num_objs, boxes, diff->w, diff->h);
if (object != NULL)
{
last_obj = obj;
if (wind_find(mk.mox, mk.moy)==window->handle &&
inside(mk.mox,mk.moy,&window->work))
obj = objc_find (object, ROOT, MAX_DEPTH, mk.mox, mk.moy);
else
obj = NIL;
if (obj!=last_obj)
{
if (setin (inv_objs, last_obj))
{
select_objc(object, last_obj, FALSE);
draw_winobject (window, last_obj);
}
if (setin (inv_objs, obj))
{
select_objc(object, obj, TRUE);
draw_winobject (window, obj);
}
}
}
check_drag(mk.mox-x_mstart, mk.moy-y_mstart, bound, &inner, diff);
diff->x = mk.mox;
diff->y = mk.moy;
draw_all (num_objs, boxes, diff->w, diff->h);
}
}while (!(event&MU_BUTTON));
draw_all (num_objs, boxes, diff->w, diff->h);
if (setin (inv_objs, obj)) /* Wieder normal darstellen */
{
select_objc(object, obj, FALSE);
draw_winobject (window, obj);
}
vsl_type (vdi_handle, SOLID);
vswr_mode (vdi_handle, MD_REPLACE); /* Modi zurücksetzen */
if (rmk != NULL)
memcpy(rmk, &mk, sizeof(MKINFO));
} /* drag_boxes */
/***************************************************************************/
VOID set_fkey(WORD scan, CONST UBYTE *str)
{
WORD obj;
if ((scan >= 0x3B00) && (scan <= 0x4400)) /* F1 - F10 */
obj =((scan - 0x3B00) / 0x100) + IF1;
else if ((scan >= 0x5400) && (scan <= 0x5D00)) /* F11 - F20 */
obj =((scan - 0x5400) / 0x100) + IFS1;
objc_setstring (desktop, obj, (BYTE*) str);
}
VOID draw_fkey (WORD scan, BOOLEAN selected)
{
WORD obj;
if ((scan >= 0x3B00) && (scan <= 0x4400)) /* F1 - F10 */
obj =((scan - 0x3B00) / 0x100) + IF1;
else if ((scan >= 0x5400) && (scan <= 0x5D00)) /* F11 - F20 */
obj =((scan - 0x5400) / 0x100) + IFS1;
select_objc(desktop, obj, selected);
draw_winobject(get_window (0), obj);
}
/***************************************************************************/
/* Diese Procedur wird bei Verschiebungen von Icons auf dem Desktop */
/* aufgerufen. (Aufruf von Routine für Ziel--Icon) */
/***************************************************************************/
LOCAL BOOLEAN drag_react (WORD src_obj, WORD dest_obj)
{
return Icon_drag(dest_obj,src_obj);
} /* drag_react */
/***************************************************************************/
WORD drag_to_desktop(const RECT r[], WORD anz, WORD m_x, WORD m_y,
BOOLEAN *mywin, MKINFO *mk)
{
RECT diff;
WINDP dest_window;
WORD dest_obj, dest_hdl;
diff.x = m_x;
diff.y = m_y;
Set_mouse (FLAT_HAND);
drag_boxes (anz, r, get_window(0), used_icons, &diff, &desk, mk);
Last_mouse ();
m_x = diff.x;
m_y = diff.y;
dest_hdl = wind_find(m_x, m_y);
dest_window = find_window (dest_hdl);
if (dest_window != NULL)
{
*mywin = TRUE;
if (dest_window->class == DESK)
{
dest_obj = objc_find (desktop, ROOT, MAX_DEPTH, m_x, m_y);
if (dest_obj>0 && setin(used_icons,dest_obj))
return dest_obj;
else
return ROOT;
}
else
return dest_window->link;
}
else if (dest_hdl >= 0) /* D&D zu anderem Programm */
{
*mywin = FALSE;
return dest_hdl;
}
return -1;
}
/***************************************************************************/
LOCAL VOID drag_objs (WINDP window, SET objs, WORD m_x, WORD m_y)
{
RECT ob, newob, diff;
WORD i, max, num_objs, result, mobutton, kstate;
WORD dest_obj;
WINDP dest_window;
SET inv_objs, help;
BOOLEAN action;
RECT all[MAX_ICON_ANZ];
graf_mkstate (&result, &result, &mobutton, &kstate);
global_shift = (kstate & 3);
if (!(mobutton&1))
return; /* Immernoch gedrückt ? */
max = setmax(objs);
for (i=setmin(objs), num_objs=0; i<=max; i++)
{
if (setin (objs, i)) /* ist invertiert */
objc_rect (desktop, i, &all[num_objs++], FALSE);
}
if (setin(objs,FKEYS))
{
setclr(inv_objs);
}
else
{
setcpy (inv_objs, used_icons);
setcpy (help, objs);
setnot (help);
setand (inv_objs, help); /* nicht sel. Objekte = inv_objs */
}
diff.x = m_x;
diff.y = m_y;
Set_mouse (FLAT_HAND);
drag_boxes (num_objs, all, window, inv_objs, &diff, &desk, NULL);
Last_mouse ();
m_x = diff.x;
m_y = diff.y;
action = FALSE;
dest_window = find_window (wind_find (m_x, m_y));
if (dest_window != NULL && dest_window->class == DESK)
{
/* Auf Desktop verschoben */
dest_obj = objc_find (desktop, ROOT, 1, m_x, m_y);
if (dest_obj==-1 || setin(objs,dest_obj) || dest_obj==ROOT || setin(objs,FKEYS))
/* Icons auf Desktop verschieben */
{
for (i=0, num_objs=0; i<=max; i++) if (setin (objs, i))
{
move_icon(i,diff.w,diff.h);
}
}
else /* Icon auf Icon : Aktion durchführen */
{
objc_rect (desktop, dest_obj, &newob, FALSE);
for (i=0, num_objs=0; i<=max; i++) if (setin (objs, i))
{
if (!drag_react(i, dest_obj))
{
ob = all[num_objs];
newob.w = ob.w;
newob.h = ob.h;
graf_movebox (newob.w, newob.h, newob.x, newob.y, ob.x, ob.y);
}
else
action = TRUE;
num_objs++;
}
}
}
else /* Icon auf Fenster : Aktion durchführen */
{
if (dest_window!=NULL)
dest_obj = dest_window->link;
else
dest_obj = -1;
for (i=0, num_objs=0; i<=max; i++) if (setin (objs, i))
{
if (!drag_react(i, dest_obj))
{
ob = all[num_objs];
ob.x += diff.w;
ob.y += diff.h;
graf_movebox (ob.w, ob.h, ob.x, ob.y, -diff.w, -diff.h);
}
else
action = TRUE;
num_objs++;
}
}
if (action) /* Nach Aktion deselektieren */
unclick_window ();
} /* drag_objs */
/***************************************************************************/
LOCAL VOID get_selected (WINDP window, SET objs, RECT *area)
{
WORD i;
RECT r;
OBJECT *object = desktop;
setclr (objs);
for (i=setmax(used_icons); i>=0; i--)
if (setin(used_icons,i))
{
objc_rect (object, i, &r, FALSE);
if (myrc_intersect(area, &r) && myrc_intersect(&window->work, &r))
setincl (objs, i);
}
} /* get_selected */
/***************************************************************************/
LOCAL VOID select_objs (WINDP window, SET objs)
{
WORD i;
OBJECT *object;
i = setmax(objs);
for (object=&desktop[i]; i>=0; i--,object--)
if (setin (objs, i) && i!=FKEYS)
{
object->ob_state |= SELECTED;
draw_winobject (window, i);
}
} /* select_objs */
/***************************************************************************/
LOCAL VOID clear_objs (WINDP window, SET objs)
{
WORD i;
OBJECT *object;
i = setmax(objs);
for (object=&desktop[i]; i>=0; i--,object--)
if (setin (objs, i) && i!=FKEYS)
{
object->ob_state &= (~SELECTED);
draw_winobject (window, i);
}
} /* clear_objs */
/***************************************************************************/
LOCAL VOID invert_objs (WINDP window, SET objs)
{
WORD i;
OBJECT *object;
i = setmax(objs);
for (object=&desktop[i]; i>=0; i--,object--)
if (setin (objs, i) && i!=FKEYS)
{
object->ob_state ^= SELECTED;
draw_winobject (window, i);
}
} /* invert_objs */
/***************************************************************************/
LOCAL VOID rubber_objs (WINDP window, MKINFO *mk)
{
WORD kstate, mobutton;
RECT r;
SET new_objs;
graf_mkstate (&r.x, &r.y, &mobutton, &kstate);
if (!(mobutton&1)) return; /* Immernoch gedrückt ? */
r.x = mk->mox;
r.y = mk->moy;
Set_mouse (POINT_HAND);
graf_rubbox (r.x, r.y, -r.x, -r.y, &r.w, &r.h);
Last_mouse ();
if (r.w < 0)
{
r.x += r.w;
r.w = - r.w;
}
if (r.h < 0)
{
r.y += r.h;
r.h = - r.h;
}
if (kstate & (K_RSHIFT|K_LSHIFT)) /* xor auswählen */
{
get_selected (window, new_objs, &r);
invert_objs (window, new_objs);
setxor (sel_objs, new_objs);
}
else /* Auswählen */
{
get_selected (window, sel_objs, &r);
select_objs (window, sel_objs);
}
sel_window = setcmp (sel_objs, NULL) ? NULL : window;
} /* rubber_objs */
/***************************************************************************/
LOCAL BOOLEAN in_icon (WORD mox, WORD moy, OBJECT *tree, WORD obj)
{
BOOLEAN ok;
CICONBLK *cicon;
RECT r, r1;
ok = FALSE;
objc_rect(tree, obj, &r, FALSE);
if (inside (mox, moy, &r)) /* Im gesamten Rechteck */
{
cicon = (CICONBLK *)get_obspec(tree, obj);
r1.x = r.x + cicon->monoblk.ib_xicon;
r1.y = r.y + cicon->monoblk.ib_yicon;
r1.w = cicon->monoblk.ib_wicon;
r1.h = cicon->monoblk.ib_ytext; /* Bis zum Text, falls Icon kürzer */
ok = inside (mox, moy, &r1); /* Im Icon */
if (! ok) /* Vielleicht im Text */
{
r1.x = r.x + cicon->monoblk.ib_xtext;
r1.y = r.y + cicon->monoblk.ib_ytext;
r1.w = cicon->monoblk.ib_wtext;
r1.h = cicon->monoblk.ib_htext;
ok = inside (mox, moy, &r1); /* Im Text */
}
}
return (ok);
} /* in_icon */
/***************************************************************************/
BOOLEAN is_icon_on_desk(WORD icon)
{
return (setin(used_icons,icon));
}
/***************************************************************************/
/* Hinzufügen eines Icons zum Desktop */
/***************************************************************************/
WORD add_icon_to_desk(WORD obj, UBYTE *text, WORD x, WORD y)
{
CICONBLK *cicon1, *cicon2;
UBYTE *str;
WORD i;
if (obj==0)
{
if (x<desk.x)
x = desk.x;
if (y<desk.y)
y = desk.y;
if (x+desktop[FKEYS].ob_width>desk.x+desk.w)
x = desk.x+desk.w-desktop[FKEYS].ob_width;
if (y+desktop[FKEYS].ob_height>desk.y+desk.h)
y = desk.y+desk.h-desktop[FKEYS].ob_height;
desktop[FKEYS].ob_x = x;
desktop[FKEYS].ob_y = y;
return 0;
}
for (i = icon_anzahl; (--i) >= 0; )
{
if (!setin(used_icons, i + FIRSTICON))
break;
}
if (i<0)
return -1;
i += FIRSTICON;
setincl(used_icons,i);
cicon1 = (CICONBLK *)get_obspec(desktop, i);
str = cicon1->monoblk.ib_ptext;
cicon2 = (CICONBLK *)get_obspec(icons, obj);
memcpy(cicon1, cicon2, sizeof(CICONBLK));
cicon1->monoblk.ib_ptext = str;
if (strlen(text) < 13)
strcpy(str, text);
else
strncpy(str, text, 12);
desktop[i].ob_x = -1;
desktop[i].ob_y = -1;
desktop[i].ob_width = icons[obj].ob_width;
desktop[i].ob_height = icons[obj].ob_height;
move_icon_to(i,x,y);
select_objc(desktop,i,FALSE);
return i;
}
/***************************************************************************/
VOID show_icon(WORD icon)
{
hide_objc(desktop, icon, FALSE);
draw_winobject(get_window(0), icon);
}
/***************************************************************************/
VOID move_icon_to(WORD icon, WORD new_x, WORD new_y)
/* Postition relativ zum Desktop (0,0) (nicht zum Bildschirm (0,0)) */
{
WINDP window;
OBJECT *obj;
RECT r, r2, r3;
WORD i, anz_x, anz_y;
anz_x = anz_y = 0;
redo:
obj = desktop+icon;
if (new_x<0)
new_x = 0;
else if (new_x+obj->ob_width>desktop[0].ob_width)
new_x = desktop[0].ob_width-obj->ob_width;
if (new_y<desk.y)
new_y = desk.y;
else if (new_y+obj->ob_height>desktop[0].ob_height)
new_y = desktop[0].ob_height-obj->ob_height;
if (icon!=FKEYS) /* keine zwei Icons auf der gleichen Position */
{
for (i=setmax(used_icons); i>=0; i--)
if (setin(used_icons,i) && (i!=icon))
{
objc_rect (desktop, FKEYS, &r2, FALSE);
objc_rect (desktop, i, &r, FALSE);
r3.x = new_x;
r3.y = new_y;
r3.w = ICON_RASTER_X;
r3.h = ICON_RASTER_Y;
if ((r.x==new_x && r.y==new_y) || myrc_intersect(&r2,&r3))
{
if (anz_x<=anz_y)
{
anz_x++;
if (new_x>(desktop[0].ob_width>>1)) /* linke Hälft */
new_x -= ICON_RASTER_X;
else
new_x += ICON_RASTER_X;
}
else
{
anz_y++;
if (new_y>(desktop[0].ob_height>>1)) /* unter Hälfte */
new_y -= ICON_RASTER_Y;
else
new_y += ICON_RASTER_Y;
}
if (anz_x==10) break;
goto redo;
}
}
}
if (obj->ob_x!=new_x || obj->ob_y!=new_y)
{
objc_rect (desktop, icon, &r, FALSE);
obj->ob_x = new_x;
obj->ob_y = new_y;
if (!(obj->ob_flags & HIDETREE))
{
hide_objc(desktop, icon, TRUE);
window = get_window(0);
redraw_window (window, &r);
hide_objc(desktop, icon, FALSE);
draw_winobject (window, icon);
}
}
window = get_window(icon); /* immer, weil vielleicht neu */
if (window!=NULL)
{
window->icon_x = obj->ob_x;
window->icon_y = obj->ob_y;
}
}
/***************************************************************************/
VOID move_icon(WORD icon, WORD diff_x, WORD diff_y)
{
if (diff_x||diff_y)
{
move_icon_to(icon, desktop[icon].ob_x+diff_x, desktop[icon].ob_y+diff_y);
}
}
/***************************************************************************/
VOID get_icon_pos(WORD icon, WORD *x, WORD *y)
{
if (icon==0)
{
*x = desktop[FKEYS].ob_x;
*y = desktop[FKEYS].ob_y;
}
else if (setin(used_icons,icon))
{
*x = desktop[icon].ob_x;
*y = desktop[icon].ob_y;
}
else
{
*x = -1;
*y = -1;
}
}
VOID set_icon_name(WORD icon, UBYTE *name)
{
CICONBLK *ptr;
if (!setin(used_icons,icon))
{
inote(1,FATALERR,8);
return;
}
ptr = (CICONBLK *)get_obspec(desktop, icon);
if (strlen(name) < 13)
strcpy(ptr->monoblk.ib_ptext, name);
else
strncpy(ptr->monoblk.ib_ptext, name, 12);
draw_winobject(get_window (0), icon);
}
/***************************************************************************/
/* Entfernen eines Icons vom Desktop */
/***************************************************************************/
VOID del_icon_from_desk(WORD obj)
{
RECT ob;
WINDP window;
if (!setin(used_icons,obj))
{
inote(1,FATALERR,7);
return;
}
window = get_window (0);
hide_objc(desktop, obj, TRUE);
select_objc(desktop,obj, FALSE);
setexcl(used_icons,obj);
if (sel_window==window)
{
setexcl(sel_objs, obj);
if (setcard(sel_objs)==0)
sel_window = NULL;
}
if (!destruct)
{
objc_rect(desktop, obj, &ob, FALSE);
redraw_window(window, &ob);
}
}
/***************************************************************************/
/* Ändert ein Icons auf dem Desktop */
/***************************************************************************/
VOID change_icon_on_desk(WORD obj, WORD icon)
{
CICONBLK *cicon1, *cicon2;
UBYTE *str;
if (is_icon_on_desk(obj))
{
cicon1 = (CICONBLK *)get_obspec(desktop, obj);
str = cicon1->monoblk.ib_ptext;
cicon2 = (CICONBLK *)get_obspec(icons, icon);
memcpy(cicon1, cicon2, sizeof(CICONBLK));
cicon1->monoblk.ib_ptext = str;
desktop[obj].ob_width = icons[icon].ob_width;
desktop[obj].ob_height = icons[icon].ob_height;
draw_winobject(get_window (0), obj);
}
}
/***************************************************************************/
/* Aufräumen der Icons */
/***************************************************************************/
VOID clearup_desktop(VOID)
{
WORD i, diff_x, diff_y;
OBJECT *object;
if (!no_desktop)
{
i = setmax(used_icons);
for (object=&desktop[i]; i>=0; i--,object--)
if (setin (used_icons, i) && i!=FKEYS)
{
diff_x = (object->ob_x%ICON_RASTER_X);
diff_y = ((object->ob_y-desk.y)%ICON_RASTER_Y);
if ((diff_x+diff_x)>ICON_RASTER_X) diff_x -= ICON_RASTER_X;
if ((diff_y+diff_y)>ICON_RASTER_Y) diff_y -= ICON_RASTER_Y;
move_icon(i, -diff_x, -diff_y);
}
}
}
/***************************************************************************/
/* Desktop zeichnen */
/***************************************************************************/
LOCAL VOID wi_draw(WINDP window, CONST RECT *r)
{
RECT r1;
r1 = window->work;
if (myrc_intersect(r, &r1))
objc_draw (desktop, ROOT, MAX_DEPTH, r1.x, r1.y, r1.w, r1.h);
}
/***************************************************************************/
/* Selektieren des Fensterinhalts */
/***************************************************************************/
LOCAL VOID wi_click (WINDP window, MKINFO *mk)
{
RECT *s = &window->work;
WORD obj, result, mobutton;
SET new_obj;
if (mk->mobutton & 2) /* Rechtsclick */
return;
if (!inside(mk->mox,mk->moy,s))
return;
obj = objc_find (desktop, ROOT, 2, mk->mox, mk->moy); /* Nur 2 Ebenen */
if (obj >= IF1 && obj <= IF10) /* Funktionstaste */
{
mk->scan_code = 0x3B00 + (obj - IF1) * 0x100;
mk->ascii_code = 0;
graf_mkstate (&result, &result, &mobutton, &result);
if (mobutton&1) /* Immernoch gedrückt ? */
evnt_button(1, 1, 0, &result, &result, &result, &result);
key_window (window, mk);
}
else if (obj >= IFS1 && obj <= IFS10) /* Shift+Funktionstaste */
{
mk->scan_code = 0x5400 + (obj - IFS1) * 0x100;
mk->ascii_code = 0;
mk->shift = TRUE;
graf_mkstate (&result, &result, &mobutton, &result);
if (mobutton & 1) /* Immernoch gedrückt ? */
evnt_button(1, 1, 0, &result, &result, &result, &result);
key_window (window, mk);
}
else
{
if (objc_find (desktop, ROOT, 1, mk->mox, mk->moy)==FKEYS)
obj = FKEYS;
if (sel_window != window || obj == FKEYS)
unclick_window (); /* Deselektieren */
if (obj == NIL)
return;
if (get_obtype(desktop, obj, NULL) == G_CICON)
{
if (!in_icon (mk->mox, mk->moy, desktop, obj))
obj = ROOT;
}
if (get_obtype(desktop, obj, NULL) == G_CICON || obj==FKEYS)
{
setclr (new_obj);
setincl (new_obj, obj); /* Aktuelles Objekt */
if (mk->breturn>1 && obj!=FKEYS) /* Doppelklick */
{
if (sel_window==window)
unclick_window ();
select_objs (window, new_obj);
sel_window = window;
setcpy(sel_objs,new_obj);
graf_mkstate (&result, &result, &mobutton, &result);
if (mobutton&1) /* Immernoch gedrückt ? */
evnt_button(1, 1, 0, &result, &result, &result, &result);
if (do_icon(obj,DO_OPEN)<0)
note(1, NOWINDOW);
}
else /* Einfachklick */
{
if (mk->kstate & (K_RSHIFT|K_LSHIFT)) /* xor Auswahl */
{
invert_objs (window, new_obj);
setxor (sel_objs, new_obj);
if (!setin (sel_objs, obj)) obj = NIL; /* Wieder deselektiert */
}
else if (!setin (sel_objs, obj)) /* Neues Objekt */
{
if (sel_window==window)
unclick_window (); /* Alte Objekte löschen */
select_objs (window, new_obj); /* Neues setzten */
setcpy(sel_objs,new_obj);
}
sel_window = (setcard(sel_objs)==0)?NULL:window;
if (obj!=NIL)
drag_objs (window, sel_objs, mk->mox, mk->moy);
else
evnt_button(1, 1, 0, &result, &result, &result, &result);
}
}
else /* auf Hintergrund geklickt */
{
if (!(mk->shift))
unclick_window (); /* Deselektieren */
if (mk->breturn == 1 && mk->mobutton & 1)
rubber_objs (window,mk); /* Gummiband-Operation */
else
{
wind_update (BEG_MCTRL); /* Mauskontrolle übernehmen */
evnt_button(1, 1, 0, &result, &result, &result, &result);
wind_update (END_MCTRL); /* Mauskontrolle übernehmen */
}
}
}
} /* wi_click */
/***************************************************************************/
LOCAL VOID wi_unclick (WINDP window)
{
clear_objs (window, sel_objs);
}
/***************************************************************************/
/* Taste für Fenster */
/***************************************************************************/
LOCAL BOOLEAN wi_key (WINDP window, MKINFO *mk)
{
if (mk->kreturn == (NKF_FUNC|NK_HELP))
{
do_action(DO_HELP);
return TRUE;
}
if (mk->kreturn == (NKF_FUNC|NK_INS))
{
set_overwrite(!overwrite);
return TRUE;
}
else if ((mk->kreturn & NKF_ALT) && (mk->scan_code >= 0x3B00 && mk->scan_code <= 0x4400))
/* Alt+Funktionstasten => Programmende mit Returncode */
{
return_code = ((mk->scan_code - 0x3B00) / 0x100) + 1;
quick_close = TRUE;
if (do_icon(0,DO_DESTRUCT)<=0)
return_code = 0;
return (TRUE);
}
else if ((mk->scan_code >= 0x3B00 && mk->scan_code <= 0x4400) ||
(mk->scan_code >= 0x5400 && mk->scan_code <= 0x5D00))
{
if (!start_play (mk->scan_code, 1)) /* Makro abspielen */
send_avkey(mk->kstate, mk->scan_code);
}
return (menu_key(mk));
} /* wi_key */
/***************************************************************************/
/* Kreieren eines Fensters */
/***************************************************************************/
LOCAL VOID crt_desktop (WORD icon, WINDP window)
{
WORD menu_height;
menu_height = 0;
window->flags = FLAGS|WI_MAIN_MENU;
if (no_desktop)
{
window->work.x = INITX - odd (desk.x);
window->work.y = (INITY - odd (desk.y)) - menu_height;
window->work.w = INITW;
window->work.h = menu_height;
}
else
{
window->doc.w = desk.w / XFAC;
window->doc.h = desk.h / YFAC;
window->xfac = XFAC;
window->yfac = YFAC;
window->work = desk;
window->w_width = window->work.w / XFAC;
window->w_hight = window->work.h / YFAC;
}
if (!no_desktop)
{
window->click = wi_click;
window->unclick = wi_unclick; /* Icons deselektieren */
}
window->key = wi_key;
window->draw = wi_draw;
set_wname(window,"qed - Desktop");
} /* crt_desktop */
/***************************************************************************/
/* Öffnen des Objekts */
/***************************************************************************/
LOCAL BOOLEAN open_desktop ()
{
BOOLEAN ok;
WINDP window;
window = get_window (0); /* Suche Desktop */
if (window!=NULL)
{
ok = TRUE;
if (!window->opened)
ok = open_window (window); /* Desktop öffnen */
else
top_window (window); /* Bringe Desktop nach oben */
}
else
ok = FALSE;
return (ok);
} /* open_desktop */
/***************************************************************************/
VOID clearup_dial(VOID)
{
WORD antw, i;
UBYTE s[10];
select_objc(clearup, CUWIN, cu_window);
disable_objc(clearup, CUICON, no_desktop);
select_objc(clearup, CUICON, cu_icon);
select_objc(clearup, CU1, cu_mode==0);
select_objc(clearup, CU2, cu_mode==1);
select_objc(clearup, CU3, cu_mode==2);
select_objc(clearup, CUWIDTH, cu_width);
itoa(cu_width2,s,10);
objc_setstring(clearup, CUWIDTH2, s);
select_objc(clearup, CUHIGH, cu_high);
itoa(cu_high2,s,10);
objc_setstring(clearup, CUHIGH2, s);
Arrow_mouse();
antw = HndlDial(clearup, 0, FALSE, NULL, NULL);
Last_mouse();
if (antw == CUOK)
{
cu_window = get_select(clearup,CUWIN);
cu_icon = get_select(clearup,CUICON);
cu_width = get_select(clearup,CUWIDTH);
cu_high = get_select(clearup,CUHIGH);
objc_getstring(clearup, CUWIDTH2, s);
cu_width2 = atoi(s);
objc_getstring(clearup, CUHIGH2, s);
cu_high2 = atoi(s);
for (i=0; i<3; i++)
if (get_select(clearup,CU1+i))
{
cu_mode = i;
break;
}
if (cu_window)
clearup_windows(cu_mode, cu_width?cu_width2:0, cu_high?cu_high2:0);
if (cu_icon)
clearup_desktop();
}
}
/***************************************************************************/
VOID info_desktop (VOID)
{
WORD antw;
objc_setstring(about, ADATUM, __DATE__);
objc_setstring(about, AVERSION, ProgrammVersion);
Arrow_mouse();
antw = HndlDial(about, 0, FALSE, NULL, NULL);
if (antw == AINFO)
HndlDial(about2, 0, FALSE, NULL, NULL);
Last_mouse();
}
VOID init_desktop (VOID)
{
WORD i, desk_type;
setclr(used_icons);
for (i=20; (--i)>=0; )
objc_setstring (desktop, IF1+i, "");
desk_type = decl_icon_type(icon_test,icon_edit,icon_exist,(BOOLEAN(*)(WORD,WORD))NULL);
add_icon(desk_type, 0);
}
BOOLEAN init2_desktop(VOID)
{
BOOLEAN erg;
erg = (create_window(0, DESK, 0, crt_desktop)!=NULL);
return erg;
}